package com.bookseek.xreader.service.dk;

import android.database.Cursor;

import com.bookseek.xreader.consts.XreaderConts;
import com.bookseek.xreader.dao.DaoSession;
import com.bookseek.xreader.dbhelper.DbSessionUtils;
import com.bookseek.xreader.params.BookSearchParams;
import com.bookseek.xreader.po.FtsBdocPo;
import com.bookseek.xreader.po.TMetaPo;
import com.bookseek.xreader.utils.DLog;
import com.bookseek.xreader.utils.JkhlUtils;
import com.bookseek.xreader.utils.LocaleUtils;
import com.bookseek.xreader.utils.MiniDataUtils;
import com.bookseek.xreader.utils.OkHttpUtils;
import com.bookseek.xreader.utils.WordTextUtils;
import com.bookseek.xreader.vo.BookListItemVo;
import com.bookseek.xreader.vo.FtsBdocVo;
import com.google.gson.reflect.TypeToken;

import org.greenrobot.greendao.database.Database;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import jackmego.com.jieba_android.JiebaSegmenter;

public class BdocService extends BaseFtsService {


    private static BdocService instance;

    public static String TAB_BDOC = "bdoc";

    public static ConcurrentHashMap<Long,Boolean> ADD_IDS = new ConcurrentHashMap<>();

    private BdocService(){}
    public static BdocService getInstance(){
        if(instance == null){
            synchronized (BdocService.class){
                if(instance == null){
                    instance = new BdocService();
                }
            }
        }
        return instance;
    }


    public FtsBdocVo getByRowid(Long rowid){
        if(rowid == null){
            return null;
        }
        FtsBdocVo bdocVo = new FtsBdocVo();
        String queryRawSql = "SELECT * FROM bdoc WHERE ROWID = "+rowid;
        Database db  = DbSessionUtils.genDaoSession().getDatabase();
        Cursor cursor = db.rawQuery(queryRawSql, null);
        try{
            // 遍历 Cursor 处理结果
            if (cursor.moveToFirst()) {
                do {
                    String bname   = cursor.getString(cursor.getColumnIndexOrThrow("bname"));
                    String bauthor = cursor.getString(cursor.getColumnIndexOrThrow("bauthor"));
                    String cname   = cursor.getString(cursor.getColumnIndexOrThrow("cname"));
                    String cont    = cursor.getString(cursor.getColumnIndexOrThrow("cont"));
                    String bchao   = cursor.getString(cursor.getColumnIndexOrThrow("bchao"));
                    String bphk   = cursor.getString(cursor.getColumnIndexOrThrow("bphk"));
                    String cphk   = cursor.getString(cursor.getColumnIndexOrThrow("cphk"));
                    String nword = cursor.getString(cursor.getColumnIndexOrThrow("nword"));
                    Long bid   = cursor.getLong(cursor.getColumnIndexOrThrow("bid"));
                    Long cid   = cursor.getLong(cursor.getColumnIndexOrThrow("cid"));
                    bdocVo.bname = bname;
                    bdocVo.bauthor =  bauthor;
                    bdocVo.cname =  cname;
                    bdocVo.cont =  cont;
                    bdocVo.bphk = bphk;
                    bdocVo.cphk = cphk;
                    bdocVo.bchao = bchao;
                    bdocVo.bid = bid;
                    bdocVo.cid = cid;
                    bdocVo.bphkCvs = JkhlUtils.parseCvs(bdocVo.bphk);
                    bdocVo.cphkCvs = JkhlUtils.parseCvs(bdocVo.cphk);
                    bdocVo.nword = nword;
                } while (cursor.moveToNext());
            }
        }finally {
            if(cursor != null && !cursor.isClosed()){
                DLog.info("testQueryTime 关闭 cursor ");
                cursor.close();
            }
        }
        return bdocVo;
    }
    /***
     *
     * @param text
     * @param matchMode 1=分词 2=不分词
     * @return
     */
    public List<String> cutWord(String text,Integer matchMode){
        if(matchMode != null &&  2==matchMode){
            List<String> strs  = new ArrayList<>(1);
            strs.add(text);
            return strs;
        }
        String newText = LocaleUtils.toMainLandSimple(JkhlUtils.toStr(text));
        if(newText.length() == 1){
            List<String> words = new ArrayList<>();
            words.add(newText);
            return words;
        }
        ArrayList<String> wordList = JiebaSegmenter.getJiebaSegmenterSingleton().getDividedStringIndex(newText);
        DLog.info("newText=",text," 分词：",wordList);
        return wordList;
    }
    public StringBuffer generateDefaultIdRange(Long startId,Long endId){
        StringBuffer sql = new StringBuffer();
        sql.append(" AND rowid >= ")
        .append(startId).append(" AND rowid <= ")
        .append(endId);
        return sql;
    }
    public StringBuffer generateWhereSql(BookSearchParams params){
        //ArrayList<String> wordList = JiebaSegmenter.getJiebaSegmenterSingleton().getDividedStringIndex(editText.getText().toString());
        StringBuffer sql = new StringBuffer();
        if(JkhlUtils.notBlank(params.keyword)){
            List<String> words = cutWord(params.keyword,params.matchMode);
            //bauthor bcont cname
            String conditionSql = String.join(" ",words);
            //移除朝代自读检索
            sql.append(" AND bdoc MATCH '-bchao:").append(conditionSql).append("'");
        }
        if(JkhlUtils.notBlank(params.bauthor)){
            List<String> bauthorWords = cutWord(params.bauthor,params.matchMode);
            String conditionSql = String.join(" ",bauthorWords);
            sql.append(" AND bdoc MATCH 'bauthor:").append(conditionSql).append("'");
        }
        if(JkhlUtils.notBlank(params.bchao)){
            List<String> bchaoWords = cutWord(params.bchao,params.matchMode);
            String conditionSql = String.join(" ",bchaoWords);
            sql.append(" AND bdoc MATCH 'bchao:").append(conditionSql).append("'");
        }
        if(JkhlUtils.notBlank(params.bcont)){
            List<String> bcontWords = cutWord(params.bcont,params.matchMode);
            String conditionSql = String.join(" ",bcontWords);
            sql.append(" AND bdoc MATCH 'cont:").append(conditionSql).append("'");
        }
        if(JkhlUtils.notBlank(params.btitle)){
            List<String> btitleWords = cutWord(params.btitle,params.matchMode);
            String conditionSql = String.join(" ",btitleWords);
            sql.append(" AND bdoc MATCH 'cname:").append(conditionSql).append("'");
        }
        return sql;
    }
    public void orderBySql(StringBuffer sql){
        sql.append(" ORDER BY rank ");
    }
    public void limitSql(StringBuffer sql,BookSearchParams params){
        Integer offset = (params.getPage()-1)*params.getPageSize();
        sql.append(" LIMIT ")
        .append(params.getPageSize())
        .append(" OFFSET ")
        .append(offset);
    }

    public List<BookListItemVo> queryByBtype(BookSearchParams params){
        List<BookListItemVo> datas = new ArrayList<>();
        List<FtsBdocVo> docs = queryList(params);
        for(FtsBdocVo vo : docs){
            BookListItemVo item = new BookListItemVo();
            item.bchaoTexts =WordTextUtils.findMatchLine(vo.bchao);
            item.bchao = item.bchaoTexts.size() > 0 ? item.bchaoTexts.stream().map(d->d.text).collect(Collectors.joining("")) : "";
            item.bauthorTexts = WordTextUtils.findMatchLine(vo.bauthor);
            item.bcontTexts = WordTextUtils.findMatchLineWithLen(vo.cont,18);
            item.btitleTexts = WordTextUtils.findMatchLine(JkhlUtils.notBlank(vo.cname) ? vo.cname : vo.bname);
            item.cid = vo.cid;
            item.bhpk = vo.bphk;
            item.cphk = vo.cphk;
            item.btype = vo.btype;
            datas.add(item);
        }
        return datas;
    }
    public List<BookListItemVo> queryShiciList(BookSearchParams params){
        params.btype = XreaderConts.BTYPE_SHICI;
        return queryByBtype(params);
    }
    public List<FtsBdocVo> queryList(BookSearchParams params){
        //CREATE VIRTUAL TABLE bdoc USING fts5(
        // bname 0 , bauthor 1, cname 2,
        // cont 3, bchao 4, btype 5,
        // cimg 6, bid 7 , cid 8, bphk 9, cphk 10
        Long startTm = System.currentTimeMillis();
        List<FtsBdocVo> datas = new ArrayList<>();
        String conditonSql = generateWhereSql(params).toString();

        StringBuffer sql = new StringBuffer("SELECT ");
        if(JkhlUtils.isBlank(conditonSql)){
            sql.append(" * ");
        }else{
            sql.append(" snippet(bdoc,0,'<b>','</b>','...',10) AS bname , ");
            sql.append(" snippet(bdoc,1,'<b>','</b>','...',10) AS bauthor , ");
            sql.append(" snippet(bdoc,2,'<b>','</b>','...',10) AS cname , ");
            sql.append(" snippet(bdoc,3,'<b>','</b>','...',40) AS cont , ");
            sql.append(" snippet(bdoc,4,'<b>','</b>','...',10) AS bchao , ");
            sql.append(" bid, ");
            sql.append(" cid, ");
            sql.append(" bphk, ");
            sql.append(" cphk ,");
            sql.append(" btype ");

        }
        sql.append(" FROM bdoc where btype = '").append(params.btype).append("' ");
        sql.append(conditonSql);
        if(JkhlUtils.isBlank(conditonSql)){
            if(XreaderConts.BTYPE_SHICI.equalsIgnoreCase(params.btype)){
                //诗词
                sql.append(generateDefaultIdRange(184618L, 224617L));
            }else if(XreaderConts.BTYPE_DIANJI.equalsIgnoreCase(params.btype)){
                sql.append(generateDefaultIdRange(17L, 116397L));
            }
        }
        if(JkhlUtils.notBlank(conditonSql)){
            orderBySql(sql);
        }
        limitSql(sql,params);
        String queryRawSql = sql.toString();
        DLog.info("Query SQL》 ",queryRawSql);
        Database db  = DbSessionUtils.genDaoSession().getDatabase();
        Cursor cursor = db.rawQuery(queryRawSql, null);
        try{
            // 遍历 Cursor 处理结果
            if (cursor.moveToFirst()) {
                do {
                    String bname   = cursor.getString(cursor.getColumnIndexOrThrow("bname"));
                    String bauthor = cursor.getString(cursor.getColumnIndexOrThrow("bauthor"));
                    String cname   = cursor.getString(cursor.getColumnIndexOrThrow("cname"));
                    String cont    = cursor.getString(cursor.getColumnIndexOrThrow("cont"));
                    String bchao   = cursor.getString(cursor.getColumnIndexOrThrow("bchao"));
                    String bphk   = cursor.getString(cursor.getColumnIndexOrThrow("bphk"));
                    String cphk   = cursor.getString(cursor.getColumnIndexOrThrow("cphk"));
                    String btype   = cursor.getString(cursor.getColumnIndexOrThrow("btype"));
                    Long bid   = cursor.getLong(cursor.getColumnIndexOrThrow("bid"));
                    Long cid   = cursor.getLong(cursor.getColumnIndexOrThrow("cid"));
                    FtsBdocVo bdocVo = new FtsBdocVo();
                    bdocVo.bname = bname;
                    bdocVo.bauthor =  bauthor;
                    bdocVo.cname =  cname;
                    bdocVo.cont =  cont;
                    bdocVo.bphk = bphk;
                    bdocVo.cphk = cphk;
                    bdocVo.bchao = bchao;
                    bdocVo.bid = bid;
                    bdocVo.cid = cid;
                    bdocVo.btype = btype;
                    datas.add(bdocVo);
                } while (cursor.moveToNext());
            }
        }finally {
            if(cursor != null && !cursor.isClosed()){
                DLog.info("testQueryTime 关闭 cursor ");
                cursor.close();
            }
        }
        Long endTm = System.currentTimeMillis();
        DLog.info("datas size=",datas.size()," 查询耗时：",endTm-startTm," ms");
        return datas;
    }

    public void testQueryTime(){
        String sql = "select snippet(bdoc,3,'<b>','</b>','...',40) as cont from bdoc where cont MATCH '二八佳人' ";
        Long startTm = System.currentTimeMillis();
        Database db  = DbSessionUtils.genDaoSession().getDatabase();
        Cursor cursor = db.rawQuery(sql.toString(), null);
        List<String> texts = new ArrayList<>();
        try{
            // 遍历 Cursor 处理结果
            if (cursor.moveToFirst()) {
                do {
                    String text   = cursor.getString(cursor.getColumnIndexOrThrow("cont"));
                    texts.add(text);
                    // 处理数据...
                } while (cursor.moveToNext());
            }
        }finally {
            if(cursor != null && !cursor.isClosed()){
                DLog.info("testQueryTime 关闭 cursor ");
                cursor.close();
            }
        }
        Long endTm = System.currentTimeMillis();
        DLog.info("texts size=",texts.size()," 查询耗时：",endTm-startTm," ms");
        texts.forEach(d->{
            DLog.info(d);
        });
    }

    public Integer countRowidStr(String rowidJoinStr){
        if(JkhlUtils.isBlank(rowidJoinStr)){
            return 0;
        }
        Long startTm = System.currentTimeMillis();
        Integer countNum = 0;
        Database db  = DbSessionUtils.genDaoSession().getDatabase();
        StringBuffer sql = new StringBuffer("SELECT count(1) num FROM ").append(TAB_BDOC).append(" ");
        sql.append(" WHERE rowid IN ( ");
        sql.append(rowidJoinStr);
        sql.append(")");
        Cursor cursor = db.rawQuery(sql.toString(), null);
        try{
            // 遍历 Cursor 处理结果
            if (cursor.moveToFirst()) {
                do {
                    countNum  = cursor.getInt(cursor.getColumnIndexOrThrow("num"));
                    // 处理数据...
                } while (cursor.moveToNext());
            }
        }finally {
            if(cursor != null && !cursor.isClosed()){
                DLog.info("countRowidStr 关闭 cursor ");
                cursor.close();
            }
        }
        Long endTm = System.currentTimeMillis();
        DLog.info("countRowid rowids.size=",rowidJoinStr.split(",").length,"countNum=",countNum," 耗时=",endTm-startTm," ms");
        return countNum;
    }
    public Integer countRowid(List<Long> rowids){
        if(rowids == null || rowids.isEmpty()){
            return 0;
        }
        Long startTm = System.currentTimeMillis();
        Integer countNum = 0;
        Database db  = DbSessionUtils.genDaoSession().getDatabase();
        StringBuffer sql = new StringBuffer("SELECT count(1) num FROM ").append(TAB_BDOC).append(" ");
        sql.append(" WHERE rowid IN ( ");
        String idsStr = rowids.stream().map(d->d.toString()).collect(Collectors.joining(","));
        sql.append(idsStr);
        sql.append(")");
        Cursor cursor = db.rawQuery(sql.toString(), null);
        try{
            // 遍历 Cursor 处理结果
            if (cursor.moveToFirst()) {
                do {
                    countNum  = cursor.getInt(cursor.getColumnIndexOrThrow("num"));
                    // 处理数据...
                } while (cursor.moveToNext());
            }
        }finally {
            if(cursor != null && !cursor.isClosed()){
                DLog.info("countRowid 关闭 cursor ");
                cursor.close();
            }
        }
        Long endTm = System.currentTimeMillis();
        DLog.info("countRowid rowids.size=",rowids.size(),"countNum=",countNum," 耗时=",endTm-startTm," ms");
        return countNum;
    }



    public int insertBatch(List<FtsBdocPo> pos){
        //Long rowid
        //                "bname , " +
        //                "bauthor, " +
        //                "cname, " +
        //                "cont, " +
        //                "bchao, " +
        //                "btype, " +
        //                "cimg UNINDEXED, " +
        //                "bid , " +
        //                "cid , " +
        //                "bphk UNINDEXED, " +
        //                "cphk UNINDEXED, " +

        Long startTm = System.currentTimeMillis();
        String colNameStr = "rowid,bname,bauthor,cname,cont,bchao,btype,cimg,bid,cid,bphk,cphk,nword";
        Integer colNameLen = colNameStr.split(",").length;
        StringBuffer sql = new StringBuffer(" INSERT INTO ").append(TAB_BDOC).append(" ( ");
        sql.append(colNameStr).append(" ) VALUES ");
        Object[] args = new Object[pos.size() * colNameLen];
        List<String> prepareList = new ArrayList<>(pos.size());
        int position = 0;
        Set<Long> addIds = new HashSet<>();
        for(int i = 0;i<pos.size();i++){
            List<String> pres = new ArrayList<>();
            FtsBdocPo po = pos.get(i);
            //rowid,bname,bauthor,cname,cont,
            // bchao,btype,cimg,bid,cid,bphk,cphk
            for(int j = 0 ;j < colNameLen;j++){
                pres.add("?");
                Object val = "";
                if(j == 0){
                    //rowid
                    val = po.cid;
                    addIds.add(po.cid);
                }else if(j == 1){
                    //bname
                    val = JkhlUtils.toStr(po.bname);
                }else if(j == 2){
                    //bauthor
                    val = JkhlUtils.toStr(po.bauthor);
                }else if(j == 3){
                    //cname
                    val = JkhlUtils.toStr(po.cname);
                }else if(j == 4){
                    //cont
                    val = JkhlUtils.toStr(po.cont);
                }else if(j == 5){
                    //bchao
                    val = JkhlUtils.toStr(po.bchao);
                }else if(j == 6){
                    //btype
                    val = JkhlUtils.toStr(po.btype);
                }else if(j == 7){
                    //cimg
                    val = JkhlUtils.toStr(po.cimg);
                }else if(j == 8){
                    //bid
                    val = (po.bid != null ? po.bid : 0L)+"";
                }else if(j == 9){
                    //cid
                    val = (po.cid != null ? po.cid : 0L)+"";
                }else if(j == 10){
                    //bphk
                    val = JkhlUtils.toStr(po.bphk);
                }else if(j == 11){
                    //cphk
                    val = JkhlUtils.toStr(po.cphk);
                }else if(j == 12){
                    val = JkhlUtils.toStr(po.nword);
                }
                args[position] = val;
                position++;
            }
            String preStr = "("+String.join(",",pres)+")";
            prepareList.add(preStr);
        }
        sql.append(String.join(",",prepareList));
        String execSql = sql.toString();
       // DLog.info("execSql=",execSql);
       // DLog.info("args=",OkHttpUtils.gson.toJson(args));

        Database db = DbSessionUtils.genDaoSession().getDatabase();
        db.beginTransaction();
        try{
            db.execSQL(execSql,args);
            db.setTransactionSuccessful();
        }catch (Exception e){
            e.printStackTrace();
            DLog.error("SQL 执行异常 ",e.getMessage(),addIds.size(),"pos.size()=",pos.size());
        }finally {
            db.endTransaction();
        }
        Long endTm = System.currentTimeMillis();
        Long minCid = pos.stream().map(d->d.cid).sorted().findFirst().orElse(null);
        DLog.info("批量插入数据条数=minCid=>",minCid,pos.size()," 耗时=",endTm-startTm," ms");
        return pos.size();
    }

    public Integer saveBdocs(List<FtsBdocPo> pos){
        if(pos == null || pos.size() == 0){
            return 0;
        }
        //cid 指定为 rowid
        List<FtsBdocPo> okPos = pos.stream().filter(d->d.cid != null).collect(Collectors.toList());
        Map<Long,FtsBdocPo> cidMap = new HashMap<>();
        okPos.forEach(d->{
            cidMap.put(d.cid,d);
        });
        Set<Long> cids = cidMap.keySet();
        Set<Long> dbCids = getExistRowid(cids,TAB_BDOC);
        List<FtsBdocPo> addPos = okPos.stream().filter(d->!dbCids.contains(d.cid)).collect(Collectors.toList());
        int okSize = okPos.size();
        int addSize = addPos.size();
        DLog.info("okSize=",okSize," addSize=",addSize);
        List<List<FtsBdocPo>> pagePos = JkhlUtils.pageDatas(addPos,XreaderConts.DB_BATCH_SIZE);
        int splitCount = pagePos.size();
        Long startTm = System.currentTimeMillis();
        int countNum = 0;
        for(int page  = 0 ;page < splitCount;page++){
            DLog.info("addSize=",addSize,"page=",page,"splitCount=",splitCount);
            List<FtsBdocPo> pageDatas = pagePos.get(page);
            countNum += insertBatch(pageDatas);
        }
        Long endTm = System.currentTimeMillis();
        DLog.info("okSize=",okSize," addSize=",addSize," 插入耗时 ",endTm-startTm," ms");
        return countNum;
    }

    public TMetaPo parseDownDataBdoc(TMetaPo po,byte[] datas){
        if(datas == null || datas.length == 0){
            return po;
        }
        DLog.info("解密数据==》");
        long aTm = System.currentTimeMillis();
        String jsonpText = new String(datas, StandardCharsets.UTF_8);
        String srcJson = MiniDataUtils.aesDecryptCBCWithIvFromBase64SafeUrlJSONP(jsonpText);
        long bTm = System.currentTimeMillis();
        DLog.info("id=",po.id,"plat=",po.plat,datas.length/1024,"KB 数据 ,解密耗时 ",bTm-aTm," ms");
        List<FtsBdocPo> bdocPos = OkHttpUtils.gson.fromJson(srcJson,new TypeToken<List<FtsBdocPo>>(){}.getType());
        if(bdocPos == null || bdocPos.size() == 0){
            DLog.error("id=",po.id,"plat=",po.plat,"解析数据条数为 0");
            return po;
        }
        String btype = Objects.equals(po.btype,XreaderConts.TMETA_BTYPE_SHICI) ? XreaderConts.BTYPE_SHICI : XreaderConts.BTYPE_DIANJI;
        List<Long> cids = bdocPos.stream().map(d->d.cid).sorted().collect(Collectors.toList());
        Integer cidCount = cids.size();
        long cTm = System.currentTimeMillis();
        DLog.info("id=",po.id,"plat=",po.plat,datas.length/1024,"KB 数据 ,JSON耗时 ",cTm-bTm," ms"," bdocPos.size=",bdocPos.size(),OkHttpUtils.gson.toJson(bdocPos.get(0)));
        for(FtsBdocPo bdoc : bdocPos){
            if(JkhlUtils.isBlank(bdoc.btype)){
                bdoc.btype = btype;
            }
        }
        saveBdocs(bdocPos);

        long tTm = System.currentTimeMillis();
        DLog.info("id=",po.id,"plat=",po.plat,"处理byte[] db 总耗时",tTm-cTm," ms"," bdocPos.size=",bdocPos.size()," 总耗时=",tTm-aTm," ms");
        //更新TMetaPo 信息
        TMetaPo upPo = new TMetaPo();
        upPo.plat = po.plat;
        upPo.id = po.id;
        upPo.bmax = cids.get(cidCount-1);
        upPo.bmin = cids.get(0);
        upPo.bcount = bdocPos.size();
        upPo.bids = cids.stream().map(d->d.toString()).collect(Collectors.joining(","));
        //判断数据库插入得数量 和 bcount
        Integer countNum = countRowid(cids);
        upPo.dflag = Objects.equals(countNum, cidCount) ? XreaderConts.TMETA_DLAG_OK : XreaderConts.TMETA_DLAG_TODO;
        DLog.info("DB countNum=",countNum," cidCount=",cidCount,"upPo.dflag=",upPo.dflag);
        TMetaService.getInstance().updateSelectiveById(upPo);
        po.bids = upPo.bids;
        po.bmax = upPo.bmax;
        po.bmin = upPo.bmin;
        po.bcount = upPo.bcount;
        po.dflag = upPo.dflag;

        return po;
    }
    public void dealDownDataAsync(TMetaPo  po,byte[] datas){
        if(datas == null || datas.length == 0){
            return;
        }
        OkHttpUtils.getInstance().getThreadPool().execute(()->{
            DLog.info("解密数据==》");
            long aTm = System.currentTimeMillis();
            String jsonpText = new String(datas, StandardCharsets.UTF_8);
            String srcJson = MiniDataUtils.aesDecryptCBCWithIvFromBase64SafeUrlJSONP(jsonpText);
            long bTm = System.currentTimeMillis();
            DLog.info(datas.length/1024,"KB 数据 ,解密耗时 ",bTm-aTm," ms");
            List<FtsBdocPo> bdocPos = OkHttpUtils.gson.fromJson(srcJson,new TypeToken<List<FtsBdocPo>>(){}.getType());
            long cTm = System.currentTimeMillis();
            DLog.info(datas.length/1024,"KB 数据 ,JSON耗时 ",cTm-bTm," ms"," bdocPos.size=",bdocPos.size(),OkHttpUtils.gson.toJson(bdocPos.get(0)));
            saveBdocs(bdocPos);
            long tTm = System.currentTimeMillis();
            DLog.info("处理byte[] db 总耗时",tTm-cTm," ms"," bdocPos.size=",bdocPos.size()," 总耗时=",tTm-aTm," ms");
        });
    }



}
